<!doctype html>
<html lang="en">
	<head>
		<title>three.js webgl - materials - shaders [Phong, Lambert]</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				background:#000;
				color:#fff;
				padding:0;
				margin:0;
				overflow:hidden;
				font-family:georgia;
				text-align:center;
			}
			h1 { }
			a { color:skyblue }
			canvas { pointer-events:none; z-index:10; }
			#d { text-align:center; margin:1em 0 -19.7em 0; z-index:0; position:relative; display:block }
			.button { background:orange; color:#fff; padding:0.2em 0.5em; cursor:pointer }
			.inactive { background:#999; color:#eee }
		</style>
	</head>

	<body>
		<div id="d">
			<h1>Blinn-Phong / Lambert materials</h1>

			<span id="rcanvas" class="button inactive">2d canvas renderer</span>
			<span id="rwebgl" class="button">WebGL renderer</span>
			<br/>

			<p><a href="http://github.com/mrdoob/three.js">Three.js</a> example

			<br/>
			<p>Best viewed in Chrome 9 or Firefox 4 using WebGL renderer.
			<p>Canvas renderer is very slow on anything other than Chrome.
			<p>Blinn-Phong shader only works in WebGL, canvas has only diffuse materials.
		</div>

		<script src="../build/Three.js"></script>

		<script src="js/Detector.js"></script>
		<script src="js/Stats.js"></script>

		<script>

			var SCREEN_WIDTH = window.innerWidth;
			var SCREEN_HEIGHT = window.innerHeight;
			var FLOOR = -250;

			var container, stats;

			var camera, scene, canvasRenderer, webglRenderer;

			var mesh, zmesh, lightMesh, geometry;

			var directionalLight, pointLight;

			var mouseX = 0, mouseY = 0;

			var windowHalfX = window.innerWidth / 2;
			var windowHalfY = window.innerHeight / 2;

			var render_canvas = 0, render_gl = 1;
			var has_gl = 0;

			var bcanvas = document.getElementById( "rcanvas" );
			var bwebgl = document.getElementById( "rwebgl" );

			init();
			animate();

			render_canvas = !has_gl;
			bwebgl.style.display = has_gl ? "inline" : "none";
			bcanvas.className = render_canvas ? "button" : "button inactive";

			function addMesh( geometry, scale, x, y, z, rx, ry, rz, material ) {

				mesh = new THREE.Mesh( geometry, material );

				mesh.scale.set( scale, scale, scale );
				mesh.position.set( x, y, z );
				mesh.rotation.set( rx, ry, rz );

				scene.add( mesh );

			}

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				scene = new THREE.Scene();

				// CAMERA

				camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 100000 );
				camera.position.z = 1000;
				scene.add( camera );

				// LIGHTS

				var ambient = new THREE.AmbientLight( 0x101010 );
				scene.add( ambient );

				directionalLight = new THREE.DirectionalLight( 0xffffff );
				directionalLight.position.set( 1, 1, 2 ).normalize();
				scene.add( directionalLight );

				pointLight = new THREE.PointLight( 0xffffff );
				scene.add( pointLight );

				// light representation

				sphere = new THREE.SphereGeometry( 100, 16, 8 );
				lightMesh = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xffaa00 } ) );
				lightMesh.scale.set( 0.05, 0.05, 0.05 );
				lightMesh.position = pointLight.position;
				scene.add( lightMesh );

				// material samples

				sphere = new THREE.SphereGeometry( 100, 32, 32 );

				var y1 = 0, y2 = - 200;

				addMesh( sphere, 1, -600, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x050505, color: 0x000000, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1, -600, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0x050505 } ) );

				addMesh( sphere, 1, -400, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0xffffff, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1, -400, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0xffffff } ) );

				addMesh( sphere, 1, -200, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0xff5500, specular: 0x555555, shininess: 10 } ) );
				addMesh( sphere, 1, -200, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0xff5500 } ) );

				addMesh( sphere, 1,    0, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0xffaa00, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1,    0, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0xffaa00 } ) );

				addMesh( sphere, 1,  200, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0x55ff00, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1,  200, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0x55ff00 } ) );

				addMesh( sphere, 1,  400, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0x0055ff, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1,  400, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0x0055ff } ) );

				addMesh( sphere, 1,  600, y1, 0, 0,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0x5500ff, specular: 0x555555, shininess: 30 } ) );
				addMesh( sphere, 1,  600, y2, 0, 0,0,0, new THREE.MeshLambertMaterial( { color: 0x5500ff } ) );

				addToruses( new THREE.TorusGeometry( 100, 20, 32, 32 ) );

				//

				if ( render_gl ) {

					try {

						webglRenderer = new THREE.WebGLRenderer();
						webglRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
						webglRenderer.domElement.style.position = "relative";
						container.appendChild( webglRenderer.domElement );
						has_gl = 1;

					} catch (e) {

					}

				}

				if ( render_canvas ) {

					canvasRenderer = new THREE.CanvasRenderer();
					canvasRenderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
					container.appendChild( canvasRenderer.domElement );

				}

				//

				stats = new Stats();
				stats.domElement.style.position = 'absolute';
				stats.domElement.style.top = '0px';
				stats.domElement.style.zIndex = 100;
				container.appendChild( stats.domElement );

				bcanvas.addEventListener("click", toggleCanvas, false);
				bwebgl.addEventListener("click", toggleWebGL, false);

				document.addEventListener('mousemove', onDocumentMouseMove, false);

			}

			function addToruses( geometry ) {

				var s = 0.85, t = s + 100, y = 200, rx = 0;

				addMesh( geometry, s, -6*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x000000, color: 0x000000, specular: 0x333333, shininess: 10 } ) );
				addMesh( geometry, s, -4*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x888888, specular: 0x333333, shininess: 10 } ) );
				addMesh( geometry, s, -2*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0xff5500, shininess: 10 } ) );
				addMesh( geometry, s,    0, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0xffaa00, shininess: 10 } ) );
				addMesh( geometry, s,  2*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0x55ff00, shininess: 10 } ) );
				addMesh( geometry, s,  4*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0x0055ff, shininess: 10 } ) );
				addMesh( geometry, s,  6*t, y, 0, rx,0,0, new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0x030303, specular: 0x5500ff, shininess: 10 } ) );

			}


			function onDocumentMouseMove(event) {

				mouseX = ( event.clientX - windowHalfX );
				mouseY = ( event.clientY - windowHalfY );

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {

				var timer = -0.0002 * Date.now();

				camera.position.x += ( mouseX - camera.position.x ) * .05;
				camera.position.y += ( - mouseY - camera.position.y ) * .05;

				camera.lookAt( scene.position );

				lightMesh.position.x = 700 * Math.cos( timer );
				lightMesh.position.z = 700 * Math.sin( timer );

				if ( render_canvas ) canvasRenderer.render( scene, camera );
				if ( render_gl && has_gl ) webglRenderer.render( scene, camera );

			}

			function toggleCanvas() {

				render_canvas = !render_canvas;
				bcanvas.className = render_canvas ? "button" : "button inactive";

				render_gl = !render_canvas;
				bwebgl.className = render_gl ? "button" : "button inactive";

				if( has_gl )
					webglRenderer.domElement.style.display = render_gl ? "block" : "none";

				canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";

			}

			function toggleWebGL() {

				render_gl = !render_gl;
				bwebgl.className = render_gl ? "button" : "button inactive";

				render_canvas = !render_gl;
				bcanvas.className = render_canvas ? "button" : "button inactive";

				if( has_gl )
					webglRenderer.domElement.style.display = render_gl ? "block" : "none";

				canvasRenderer.domElement.style.display = render_canvas ? "block" : "none";

			}
		</script>

	</body>
</html>
